#include "epicure.h"

int CardlistCount(LPHEAD head)
{
	int curr = 0;
	LPITEM item = head;

	while (item != nullptr)
	{
		item = item->next;
		curr++;
	}
	return curr;
}

LPITEM lastitem(LPITEM item)
{
	if (item == nullptr)return nullptr;

	LPITEM curritem = item;
	while (curritem->next != nullptr)
	{
		curritem = curritem->next;
	}
	return curritem;
}

void CardlistAdd(LPHEAD& head, CTX item)
{
	LPCTX ctx = new CTX;
	*ctx = item;

	LPITEM newitem = new Item;

	newitem->content = ctx;
	newitem->next = nullptr;

	if (head != nullptr)
	{
		const LPITEM last = lastitem(head);
		last->next = newitem;
	}
	else head = newitem;
}

void CardlistRemove(LPHEAD& head, int index)
{
	// if the index is zero
	if (index == 0)
	{
		const LPITEM newhead = head->next;
		delete head;
		head = newhead;
		return;
	}

	// if the index is not zero
	const int prev = index - 1;

	int currindex = 0;
	LPITEM curritem = head;
	LPITEM previtem = nullptr;

	while (curritem != nullptr)
	{
		if (currindex == prev)previtem = curritem;
		else if (currindex == index)
		{
			const LPITEM nextitem = curritem->next;
			delete curritem->content;
			delete curritem;
			curritem = nextitem;
			currindex++;
			if (nextitem == nullptr)
			{
				previtem->next = nullptr;
				return;
			}
		}

		if (currindex == index + 1)
		{
			previtem->next = curritem;
		}

		currindex++;
		curritem = curritem->next;
	}
}

void CardlistInsert(LPHEAD& head, int index, CTX item)
{
	LPCTX ctx = new CTX;
	*ctx = item;

	LPITEM newitem = new Item;

	newitem->content = ctx;
	newitem->next = nullptr;

	LPITEM alter = head;

	int ind = index;
	while (ind > 1)
	{
		ind--;
		alter = alter->next;
	}

	if (head == nullptr)
	{
		newitem->next = head;
		head = newitem;
	}
	else if (index == 0)
	{
		const LPHEAD prevhead = head;
		head = newitem;
		head->next = prevhead;
	}
	else
	{
		newitem->next = alter->next;
		alter->next = newitem;
	}
}

LPITEM CardlistAt(LPHEAD head, int index)
{
	LPITEM curr = head;
	while (index > 0)
	{
		curr = curr->next;
		index--;
	}
	return curr;
}

LPITEM CardlistLastitem(LPHEAD head)
{
	return (lastitem(head));
}

VOID CardlistClear(LPHEAD& head)
{
	while(head!=nullptr) CardlistRemove(head, 0);
}